﻿// Learn more about F# at http://fsharp.net

Program ::= StateDefinition
            Main

StateDefinition ::= "type GameState = " {Labels}
                    EntityDefinition

EntityDefinition ::= empty
                   | EntityDefinition";" EntityDefinitions
                     
EntityDefinition ::= "type" [EntityName] "= {" Labels "}"

Labels ::= Label
         | Label";" Labels        

Label ::= [Nome] ":" Type
        | [Nome] ":" Type "::" Rule

Type ::= [Primitive]
       | [EntityType]                           //Il tipo dell'entita' se non primitivo
       | Type "->" Type                         //fun
       | Type "*" Type                          //tuples
       | Type "+" Type                          //union case
       | Table "<"Type">"                       //tabelle, liste
       | Rule "<"Type">"                        //regole su un tipo
       | Ref "<"Type">"                         //reference
       | Fk "<"Type">"                          //foreign key per l'ottimizzazione da non eseguirci le regole
       | "Sctipt <" Type "," Type ">"           //script
       
Rule ::= Term

Term ::= let [X] "=" Term in Term               //let assignment
       | fun [X] "->" Term                      //lambda expression
       | if Term then Term else Term            //if then else construct
       | Term Term                              //function application
       | !Term                                  //reference
       | Term ":=" Term                         //assegnazione a un ref
       | "bind" Term Term                       //monadic binding
       | yield                                  //monadic yeld
       | return Term                            //monadic return
       | "run" Term                             //script run
       | Term";" Term                           //script sequential prima 1 poi 2
       | Term "=>" Term                         //dati 2 script il primo ti da un option di a, esegui il primo finche' non da' un some di a, poi avvia script 2. come while {1} 2
       | Term "\or" Term                        //parallel first script
       | Term "\and" Term                       //parallel script

Main ::= "State0 = " Term
         "Script0 = " Term 
